package com.ruoyi.system.service.impl

import com.ruoyi.common.annotation.DataScope
import com.ruoyi.common.constant.UserConstants
import com.ruoyi.common.core.domain.TreeSelect
import com.ruoyi.common.core.domain.entity.SysDept
import com.ruoyi.common.core.domain.entity.SysUser
import com.ruoyi.common.core.text.Convert.toLongArray
import com.ruoyi.common.exception.ServiceException
import com.ruoyi.common.utils.MyStringUtils
import com.ruoyi.common.utils.SecurityUtils.userId
import com.ruoyi.common.utils.spring.SpringUtils
import com.ruoyi.system.mapper.SysDeptMapper
import com.ruoyi.system.mapper.SysRoleMapper
import com.ruoyi.system.service.ISysDeptService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

/**
 * 部门管理 服务实现
 *
 * @author ruoyi
 */
@Service
open class SysDeptServiceImpl : ISysDeptService {
    @Autowired
    private lateinit var deptMapper: SysDeptMapper

    @Autowired
    private lateinit var roleMapper: SysRoleMapper

    /**
     * 查询部门管理数据
     *
     * @param dept 部门信息
     * @return 部门信息集合
     */
    @DataScope(deptAlias = "d")
    override fun selectDeptList(dept: SysDept?): MutableList<SysDept> {
        return deptMapper.selectDeptList(dept)
    }

    /**
     * 查询部门树结构信息
     *
     * @param dept 部门信息
     * @return 部门树信息集合
     */
    override fun selectDeptTreeList(dept: SysDept?): List<TreeSelect> {
        val depts = SpringUtils.getAopProxy(this).selectDeptList(dept)
        val list= buildDeptTreeSelect(depts)
        return  list
    }

    /**
     * 构建前端所需要树结构
     *
     * @param depts 部门列表
     * @return 树结构列表
     */
    override fun buildDeptTree(depts: MutableList<SysDept>): MutableList<SysDept> {
        var returnList: MutableList<SysDept> = mutableListOf()
        val tempList = depts.map { obj: SysDept-> obj.deptId }.toMutableList()
        for (dept in depts) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.parentId)) {
                recursionFn(depts, dept)
                returnList.add(dept)
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts
        }
        return returnList
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param depts 部门列表
     * @return 下拉树结构列表
     */
    override fun buildDeptTreeSelect(depts: MutableList<SysDept>): MutableList<TreeSelect> {
        val deptTrees = buildDeptTree(depts)
        return deptTrees.map { dept: SysDept -> TreeSelect(dept) }.toMutableList()
    }

    /**
     * 根据角色ID查询部门树信息
     *
     * @param roleId 角色ID
     * @return 选中部门列表
     */
    override fun selectDeptListByRoleId(roleId: Long?): List<Long> {
        val role = roleMapper.selectRoleById(roleId)
        return deptMapper.selectDeptListByRoleId(roleId, role!!.isDeptCheckStrictly)
    }

    /**
     * 根据部门ID查询信息
     *
     * @param deptId 部门ID
     * @return 部门信息
     */
    override fun selectDeptById(deptId: Long?): SysDept? {
        return deptMapper.selectDeptById(deptId)
    }

    /**
     * 根据ID查询所有子部门（正常状态）
     *
     * @param deptId 部门ID
     * @return 子部门数
     */
    override fun selectNormalChildrenDeptById(deptId: Long?): Int {
        return deptMapper.selectNormalChildrenDeptById(deptId)
    }

    /**
     * 是否存在子节点
     *
     * @param deptId 部门ID
     * @return 结果
     */
    override fun hasChildByDeptId(deptId: Long?): Boolean {
        val result = deptMapper.hasChildByDeptId(deptId)
        return result > 0
    }

    /**
     * 查询部门是否存在用户
     *
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    override fun checkDeptExistUser(deptId: Long?): Boolean {
        val result = deptMapper.checkDeptExistUser(deptId)
        return result > 0
    }

    /**
     * 校验部门名称是否唯一
     *
     * @param dept 部门信息
     * @return 结果
     */
    override fun checkDeptNameUnique(dept: SysDept): Boolean {
        val deptId = if (MyStringUtils.isNull(dept.deptId)) -1L else dept.deptId
        val info = deptMapper.checkDeptNameUnique(dept.deptName, dept.parentId)
        return if (MyStringUtils.isNotNull(info) && info!!.deptId != deptId) {
            UserConstants.NOT_UNIQUE
        } else UserConstants.UNIQUE
    }

    /**
     * 校验部门是否有数据权限
     *
     * @param deptId 部门id
     */
    override fun checkDeptDataScope(deptId: Long?) {
        if (!SysUser.isAdmin(userId)) {
            val dept = SysDept()
            dept.deptId = deptId
            val depts= SpringUtils.getAopProxy(this).selectDeptList(dept)
            if (MyStringUtils.isEmpty(depts)) {
                throw ServiceException("没有权限访问部门数据！")
            }
        }
    }

    /**
     * 新增保存部门信息
     *
     * @param dept 部门信息
     * @return 结果
     */
    override fun insertDept(dept: SysDept): Int {
        val info = deptMapper.selectDeptById(dept.parentId)
        // 如果父节点不为正常状态,则不允许新增子节点
        if (UserConstants.DEPT_NORMAL != info!!.status) {
            throw ServiceException("部门停用，不允许新增")
        }
        dept.ancestors = info.ancestors + "," + dept.parentId
        return deptMapper.insertDept(dept)
    }

    /**
     * 修改保存部门信息
     *
     * @param dept 部门信息
     * @return 结果
     */
    override fun updateDept(dept: SysDept): Int {
        val newParentDept = deptMapper.selectDeptById(dept.parentId)
        val oldDept = deptMapper.selectDeptById(dept.deptId)
        if (MyStringUtils.isNotNull(newParentDept) && MyStringUtils.isNotNull(oldDept)) {
            val newAncestors = newParentDept?.ancestors + "," + newParentDept?.deptId
            val oldAncestors = oldDept?.ancestors
            dept.ancestors = newAncestors
            oldAncestors?.let { updateDeptChildren(dept.deptId, newAncestors, it) }
        }
        val result = deptMapper.updateDept(dept)
        if (UserConstants.DEPT_NORMAL == dept.status && MyStringUtils.isNotEmpty(dept.ancestors)
                && "0"!=dept.ancestors) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentDeptStatusNormal(dept)
        }
        return result
    }

    /**
     * 修改该部门的父级部门状态
     *
     * @param dept 当前部门
     */
    private fun updateParentDeptStatusNormal(dept: SysDept) {
        val ancestors = dept.ancestors
        val deptIds = toLongArray(ancestors)
        deptMapper.updateDeptStatusNormal(deptIds)
    }

    /**
     * 修改子元素关系
     *
     * @param deptId 被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    fun updateDeptChildren(deptId: Long?, newAncestors: String?, oldAncestors: String) {
        val children = deptMapper.selectChildrenDeptById(deptId)
        for (child in children) {
            child.ancestors = child.ancestors?.replaceFirst(oldAncestors.toRegex(), newAncestors!!)
        }
        if (children.isNotEmpty()) {
            deptMapper.updateDeptChildren(children)
        }
    }

    /**
     * 删除部门管理信息
     *
     * @param deptId 部门ID
     * @return 结果
     */
    override fun deleteDeptById(deptId: Long?): Int {
        return deptMapper.deleteDeptById(deptId)
    }

    /**
     * 递归列表
     */
    private fun recursionFn(list: List<SysDept?>?, t: SysDept?) {
        // 得到子节点列表
        val childList = getChildList(list, t)
        t!!.children = childList
        for (tChild in childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild)
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private fun getChildList(list: List<SysDept?>?, t: SysDept?): List<SysDept?> {
        val tlist: MutableList<SysDept?> = mutableListOf()
        val it = list!!.iterator()
        while (it.hasNext()) {
            val n = it.next()
            if (MyStringUtils.isNotNull(n!!.parentId) && n.parentId == t!!.deptId) {
                tlist.add(n)
            }
        }
        return tlist
    }

    /**
     * 判断是否有子节点
     */
    private fun hasChild(list: List<SysDept?>?, t: SysDept?): Boolean {
        return getChildList(list, t).isNotEmpty()
    }
}
